/* Copyright (c) CERN (except method fwt)
 * * Artistic License 2.0
 * */

import java.util.Random;
import java.lang.Math;

/**
 * Haar wavelet based pseudo distribution
 *
 * @author Xavier Grehant
 */
public class Wavelet extends DistroUtils implements Distro {

/**
 * Parameters of the distribution: values in frequency space
 */
   int[] params;

/**
 * A uniform random number generator.
 */
   Random rand;

/**
 * Constructor taking the parameters of the distribution.
 * @param params parameters of the distro.
 */
   public Wavelet(int[] params) {
      this.params = params;
      rand = new Random();
   }

/**
 * Constructor taking a sample set.
 * @param array the sample set.
 */
   public Wavelet(int[] array) {
      rand = new Random();
      array = checkSize(array);
      Arrays.sort(array);
      params = fwt(array);
   }

/**
 * Takes previous power of two from sample size.
 * @return subset of samples of size the previous power of two.
 * @param samples non-sorted samples.
 */
   int[] checkSize(int[samples]) {
      int power = 0;
      while (samples.length <= Math.pow(2, power + 1))
         power++;
      int[] output = new int[];
      System.arrayCopy(samples, 0, output, 0, Math.pow(2, power));
      return output;
   }

/**
 * Fast Wavelet Transform.
 * See http://en.wikipedia.org/wiki/Discrete_wavelet_transform
 *
 * This method is in the public domain.
 * It is not subject to copyright. I am not the author.
 *
 * @return the wavelet parameters
 * @param samples the signal, or sorted samples.
 */
   int[] fwt(int[] samples) {
      //This function assumes input.length=2^n, n>1
      int[] output = new int[input.length];

      for (int length = input.length >> 1; ; length >>= 1) {
      //length=2^n, WITH DECREASING n
         for (int i = 0; i < length; i++) {
            int sum = input[i * 2] + input[i * 2 + 1];
            int difference = input[i * 2] - input[i * 2 + 1];
            output[i] = sum;
            output[length + i] = difference;
         }
         if (length == 1) 
            return output;

         //Swap arrays to do next iteration
         System.arraycopy(output, 0, input, 0, length << 1);
      }
   }

/**
 * Random number generator according to the pseudo-distribution.
 * @return random number according to the pseudo-distribution.
 */
   public double nextDouble() {
      return;
   }

/**
 * Cumulative density function of the pseudo-distribution.
 * @return P(X <= 'limit')
 * @param the point at which the cdf is calculated.
 */
   public double cdf(int limit) {
      return;
   }
}
